package com.chushouya.product.service.admin.impl;

import com.general.framework.core.lang.*;
import com.chushouya.common.constant.ProductStatusEnum;
import com.chushouya.common.support.Contexts;
import com.general.framework.core.enums.DelFlagEnum;
import com.general.framework.core.exception.Ex;
import com.general.framework.core.schema.PageResult;
import com.chushouya.product.dao.entity.ProductEntity;
import com.chushouya.product.dao.repository.ProductRepository;
import com.chushouya.product.dto.admin.product.ProductDetailDTO;
import com.chushouya.product.dto.admin.product.ProductListDTO;
import com.chushouya.product.dto.admin.product.query.ProductQuery;
import com.chushouya.product.service.admin.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

@Service
@Slf4j
public class ProductServiceImpl implements ProductService {

    @Resource
    private ProductRepository productRepository;

//
//    @Resource
//    private ProductSkuService productSkuService;
//
//    @Resource
//    private ConfigRpcApi configRpcApi;


    @Override
    public PageResult<ProductListDTO> selectProductPageResult(ProductQuery query) {
        final List<Integer> statusIn = Lists.asList(ProductStatusEnum.offline.value(), ProductStatusEnum.online.value());
        query.setStatusIn(statusIn);
        PageResult<ProductEntity> pageResult = productRepository.selectPage(query);
        return PageResult.of(pageResult, ProductListDTO.class);
    }

    @Override
    public ProductDetailDTO getProductDetail(Long productId) {
        Check.notNull(productId, "商品ID不能为空");
        ProductDetailDTO product = Beans.copy(productRepository.selectByPrimaryKey(productId), ProductDetailDTO.class);
//        product.setProductSkuList(productSkuService.getProductSkuList(productId));
        return product;
    }

    @Override
    public Boolean hasProductBindBrand(Long brandId) {
        ProductQuery query = new ProductQuery();
        query.setBrandId(brandId);
//        return productRepository.selectCount(query) > Numbers.INTEGER_ZERO;
        return false;
    }

    @Async
    @Override
    public void syncBrandName(Long brandId, String brandName) {

//        productRepository.updateBrandName(brandId, brandName);
    }

    @Override
    public Boolean hasProductBindCategory(Long categoryId) {
        ProductQuery query = new ProductQuery();
        query.setCategoryId(categoryId);
//        return productRepository.selectCount(query) > Numbers.INTEGER_ZERO;
        return false;
    }

    @Override
    public Boolean hasProductBindSeries(Long seriesId) {
        ProductQuery query = new ProductQuery();
        query.setSeriesId(seriesId);
//        return productRepository.selectCount(query) > Numbers.INTEGER_ZERO;
        return false;
    }


    private ProductEntity selectProduct(Long productId) {
        Check.notNull(productId, "productId can not be null");
        final ProductEntity productEntity = productRepository.selectByPrimaryKey(productId);
        Check.notNull(productEntity, "商品不存在");
        return productEntity;
    }

    private void setHandleInfo(ProductEntity update) {
        update.setHandleUser(Contexts.getUserContext().getUserName());
        update.setUpdateTime(Dates.getTimeNow());
    }


    @Override
    public void setOnline(Long productId) {
        final ProductEntity update = new ProductEntity();
        update.setProductId(productId);
        update.setStatus(ProductStatusEnum.online.value());
        this.setHandleInfo(update);
        productRepository.updateByPrimaryKeySelective(update);

//        AsyncManager.me().executeDelay5s(ProductAsyncFactory.clearProductPageResultCache(productId));
    }

    @Override
    public void setOffline(Long productId) {
        final ProductEntity productEntity = this.selectProduct(productId);

        if (Objects.equals(productEntity.getStatus(), ProductStatusEnum.offline.value())) {
            throw Ex.business("当前状态不可下架[{}]", ProductStatusEnum.getDesc(productEntity.getStatus()));
        }
        final ProductEntity update = new ProductEntity();
        update.setProductId(productId);
        update.setStatus(ProductStatusEnum.offline.value());
        this.setHandleInfo(update);
        productRepository.updateByPrimaryKeySelective(update);

//        AsyncManager.me().executeDelay5s(ProductAsyncFactory.clearProductPageResultCache(productId));
    }

    @Override
    public void removeProduct(Long productId) {
        final ProductEntity productEntity = this.selectProduct(productId);
        if (Objects.equals(productEntity.getStatus(), ProductStatusEnum.online.value())) {
            throw Ex.business("上架商品不能删除");
        }
        final ProductEntity update = new ProductEntity();
        update.setProductId(productId);
        update.setDelFlag(DelFlagEnum.delete.getValue());
        this.setHandleInfo(update);
        productRepository.updateByPrimaryKeySelective(update);

//        AsyncManager.me().executeDelay5s(ProductAsyncFactory.clearProductPageResultCache(productId));
    }

    @Override
    public void editProductSort(Long productId, Integer sort) {
        Validate.isNull(sort, "排序不能为空");
        Validate.isFalse(productRepository.existsWithPrimaryKey(productId), "商品不存在");
        ProductEntity productEntity = new ProductEntity();
        productEntity.setProductId(productId);
        productEntity.setSort(sort);
        productRepository.updateByPrimaryKeySelective(productEntity);

//        AsyncManager.me().executeDelay5s(ProductAsyncFactory.clearProductPageResultCache(productId));
    }

    @Override
    public boolean isNewProduct(Long productId) {
//        final ProductEntity productEntity = productRepository.selectOneWithProperties(productId, "productId", "status");
//        return Objects.equals(productEntity.getStatus(), ProductStatusEnum.cache.value());
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncProductMaxPrice(Long productId) {
        ProductEntity update = new ProductEntity();
//        update.setProductId(productId);
//        update.setMaxPrice(productSkuService.getSkuMaxPrice(productId));
//        final BigDecimal skuOpenedMaxPrice = productSkuService.getSkuOpenedMaxPrice(productId);
//        if (skuOpenedMaxPrice.compareTo(BigDecimal.ZERO) > 0) {
//            update.setOpenedMaxPrice(skuOpenedMaxPrice);
//        } else {
//            update.setOpenedMaxPrice(update.getMaxPrice());
//        }
        productRepository.updateByPrimaryKeySelective(update);
    }

}
